#define LENGTH 100
#define DIRECT_LENGTH 10

typedef struct Block {
    int id; //盘块号
    int freeNum; //空闲盘块数
    vector<int> free; //栈，超级块用到
} Block;
vector<vector<Block>> groups;//盘块组
Block superBlock; //超级块

//一级索引
typedef struct IndexOne {
    int data[LENGTH];
} IndexOne;

//二级索引
typedef struct IndexTwo {
    struct IndexOne *one[LENGTH];
} IndexTwo;

//三级索引
typedef struct IndexThree {
    struct IndexTwo *two[LENGTH];
} IndexThree;

//i结点
typedef struct Index {
    int direct[DIRECT_LENGTH];
    IndexOne *one;
    IndexTwo *two;
    IndexThree *three;
} Index;

typedef struct FCB {
    char fileName[30]; //文件名
    int type; //文件类型
    int size; //文件大小
    struct FCB *next; //下一个同级目录文件
    struct FCB *father; //上级文件
    struct FCB *sub; //下级文件
    Index *index; //i结点，保存文件分配的盘块号
} FCB;

FCB *root; //根结点
FCB *present; //当前目录结点
FCB *finding; //查找到的结点

int blockNum; //空闲盘块总数
int remainNum; //空闲盘块剩余数
int groupSize; //组大小

char path[300]; //用户所在路径

void init(); //初始化

void build(vector<int> blockList); //构建

void buildGroup(vector<int> blockList); //构建盘块组

void buildLeader(); //构建组长块

void buildSuperBlock(); //构建超级块

void printGroups(); //打印空闲盘块组

void printSuperBlock(); //打印超级块

vector<int> allocateBlock(int fileSize); //分配盘块

vector<int> allocateBlockContinuous(int fileSize);

void releaseBlock(int size,int *blockList); //释放盘块

void copyToSuperBlock(Block &block); //复制盘块到超级块

void copyToBlock(Block &block); //复制超级块到盘块

void refactor(); //重构空闲盘块组

bool cmp(int a, int b); //比较

void mkdir(); //创建文件夹

bool isFileExist(char fileName[], int type); //判断文件是否存在

void addNode(FCB *fcb); //添加结点

void deleteNodeWithoutFree(FCB *fcb); //将结点从树形结构中删除，当前节点不释放内存

void deleteNode(FCB *fcb); //删除节点并释放内存

void ls(); //显示当前目录下的文件

void ll(); //显示当前目录下文件的详细信息

void cd(); //切换目录

void touch(); //新建文件

void rmdir(); //删除目录

void rm(); //删除

void recursiveDelete(FCB *fcb); //递归删除

void changeFileSize(FCB *fcb, int type); //改变目录大小

void tree(FCB *fcb, int level); //显示树形文件结构

void help(); //显示帮助信息

void block(FCB *fcb, char pathName[]); //显示所有文件占用的盘块号

int *getIndexList(FCB *fcb); //获取文件占用盘块号列表

void setDirect(int fileSize, vector<int> allocate, Index *index); //设置直接地址

void setIndexOne(int fileSize, vector<int> allocate, Index *index);//设计一级索引

void setIndexTwo(int fileSize, vector<int> allocate, Index *index); //设置一级索引

void setIndex(FCB *fcb, const vector<int>& allocate); //设置索引